/*
 * Copyright (c) 2011, Michael van der Westhuizen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    - Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    - Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef PYXMLSEC1_KEYINFO_C_MCVDW_20110126
#define PYXMLSEC1_KEYINFO_C_MCVDW_20110126

#include "pyxmlsec.h"

#include <xmlsec/keyinfo.h>



static PyObject * xmlsec1_xmlSecKeyInfoNodeRead(PyObject * self, PyObject * args, PyObject * kwds)
{
    PyObject * arg1;
    PyObject * arg2;
    PyObject * arg3;
    xmlNodePtr keyInfoNode;
    xmlSecKeyPtr key;
    xmlSecKeyInfoCtxPtr keyInfoCtx;

    static char * kwlist[] = {"keyInfoNode", "key", "keyInfoCtx", NULL};

    arg1 = arg2 = arg3 = NULL;
    keyInfoNode = NULL;
    key = NULL;
    keyInfoCtx = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO", kwlist, &arg1, &arg2, &arg3))
    {
        return NULL;
    }

    if (NULL == (keyInfoNode = xmlsec1mod_unwrap_xmlNodePtr(arg1)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlNodePtr);
        return NULL;
    }

    if (NULL == (key = xmlsec1mod_unwrap_xmlSecKeyPtr(arg2)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyPtr);
        return NULL;
    }

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg3)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    if (0 != xmlSecKeyInfoNodeRead(keyInfoNode, key, keyInfoCtx))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyInfoNodeRead);
        return NULL;
    }

    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoNodeWrite(PyObject * self, PyObject * args, PyObject * kwds)
{
    PyObject * arg1;
    PyObject * arg2;
    PyObject * arg3;
    xmlNodePtr keyInfoNode;
    xmlSecKeyPtr key;
    xmlSecKeyInfoCtxPtr keyInfoCtx;

    static char * kwlist[] = {"keyInfoNode", "key", "keyInfoCtx", NULL};

    arg1 = arg2 = arg3 = NULL;
    keyInfoNode = NULL;
    key = NULL;
    keyInfoCtx = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO", kwlist, &arg1, &arg2, &arg3))
    {
        return NULL;
    } 

    if (NULL == (keyInfoNode = xmlsec1mod_unwrap_xmlNodePtr(arg1)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlNodePtr);
        return NULL;
    } 

    if (NULL == (key = xmlsec1mod_unwrap_xmlSecKeyPtr(arg2)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyPtr);
        return NULL;
    } 

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg3)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    if (0 != xmlSecKeyInfoNodeWrite(keyInfoNode, key, keyInfoCtx))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyInfoNodeWrite);
        return NULL;
    }

    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxCreate(PyObject * self, PyObject * args, PyObject * kwds)
{
    PyObject * arg1;
    xmlSecKeysMngrPtr keysMngr;
    xmlSecKeyInfoCtxPtr ptr;
    PyObject * ret;

    static char * kwlist[] = {"keysMngr", NULL};

    arg1 = NULL;
    keysMngr = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &arg1))
    {
        return NULL;
    }

    if (NULL != arg1 || Py_None != arg1)
    {
        if (NULL == (keysMngr = xmlsec1mod_unwrap_xmlSecKeysMngrPtr(arg1)))
        {
            ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeysMngrPtr);
            return NULL;
        }
    }

    if (NULL == (ptr = xmlSecKeyInfoCtxCreate(keysMngr)))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyInfoCtxCreate);
        return NULL;
    }

    if (NULL == (ret = xmlsec1mod_wrap_xmlSecKeyInfoCtxPtr(ptr)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_wrap_xmlSecKeyInfoCtxPtr);
        xmlSecKeyInfoCtxDestroy(ptr);
        return NULL;
    }

    return ret;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxDestroy(PyObject * self, PyObject * arg)
{
    xmlSecKeyInfoCtxPtr keyInfoCtx;

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    xmlSecKeyInfoCtxDestroy(keyInfoCtx);
    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxInitialize(PyObject * self, PyObject * args, PyObject * kwds)
{
    PyObject * arg1;
    PyObject * arg2;
    xmlSecKeyInfoCtxPtr keyInfoCtx;
    xmlSecKeysMngrPtr keysMngr;

    static char * kwlist[] = {"keyInfoCtx", "keysMngr", NULL};

    arg1 = arg2 = NULL;
    keyInfoCtx = NULL;
    keysMngr = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, &arg1, &arg2))
    {
        return NULL;
    }

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg1)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    if (NULL != arg2 || Py_None != arg2)
    {
        if (NULL == (keysMngr = xmlsec1mod_unwrap_xmlSecKeysMngrPtr(arg2)))
        {
            ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeysMngrPtr);
            return NULL;
        }
    }

    if (0 != xmlSecKeyInfoCtxInitialize(keyInfoCtx, keysMngr))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyInfoCtxInitialize);
        return NULL;
    }

    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxFinalize(PyObject * self, PyObject * arg)
{
    xmlSecKeyInfoCtxPtr keyInfoCtx;

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    xmlSecKeyInfoCtxFinalize(keyInfoCtx);
    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxReset(PyObject * self, PyObject * arg)
{
    xmlSecKeyInfoCtxPtr keyInfoCtx;

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    xmlSecKeyInfoCtxReset(keyInfoCtx);
    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxCopyUserPref(PyObject * self, PyObject * args, PyObject * kwds)
{
    PyObject * arg1;
    PyObject * arg2;
    xmlSecKeyInfoCtxPtr dst;
    xmlSecKeyInfoCtxPtr src;
    
    static char * kwlist[] = {"dst", "src", NULL};
    
    arg1 = arg2 = NULL;
    dst = src = NULL;
        
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &arg1, &arg2))
    {
        return NULL;
    }

    if (NULL == (dst = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg1)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    if (NULL == (src = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg2)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    if (0 != xmlSecKeyInfoCtxCopyUserPref(dst, src))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyInfoCtxCopyUserPref);
        return NULL;
    }

    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxCreateEncCtx(PyObject * self, PyObject * arg)
{
    xmlSecKeyInfoCtxPtr keyInfoCtx;

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    if (0 != xmlSecKeyInfoCtxCreateEncCtx(keyInfoCtx))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyInfoCtxCreateEncCtx);
        return NULL;
    }

    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxDebugDump(PyObject * self, PyObject * args, PyObject * kwds)
{
    PyObject * arg1;
    PyObject * arg2;
    xmlSecKeyInfoCtxPtr keyInfoCtx;
    PyFileObject * output;
    FILE * fp;

    static char * kwlist[] = {"keyInfoCtx", "output", NULL};

    arg1 = arg2 = NULL;
    keyInfoCtx = NULL;
    fp = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &arg1, &arg2))
    {
        return NULL;
    }

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg1)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    if (!PyFile_Check(arg2))
    {
        PyErr_SetString(PyExc_TypeError, "output must be a file opened for writing");
    }

    output = (PyFileObject *)arg2;

    if (NULL == (fp = PyFile_AsFile(arg2)))
    {
        ENSURE_EXCEPTION_SET(PyFile_AsFile);
        return NULL;
    }

    Py_INCREF(arg1);
    PyFile_IncUseCount(output);
    Py_BEGIN_ALLOW_THREADS
    xmlSecKeyInfoCtxDebugDump(keyInfoCtx, fp);
    Py_END_ALLOW_THREADS
    PyFile_DecUseCount(output);
    Py_DECREF(arg1);

    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyInfoCtxDebugXmlDump(PyObject * self, PyObject * args, PyObject * kwds)
{
    PyObject * arg1;
    PyObject * arg2;
    xmlSecKeyInfoCtxPtr keyInfoCtx;
    PyFileObject * output;
    FILE * fp;

    static char * kwlist[] = {"keyInfoCtx", "output", NULL};

    arg1 = arg2 = NULL;
    keyInfoCtx = NULL;
    fp = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO", kwlist, &arg1, &arg2))
    {
        return NULL;
    }

    if (NULL == (keyInfoCtx = xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr(arg1)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_unwrap_xmlSecKeyInfoCtxPtr);
        return NULL;
    }

    if (!PyFile_Check(arg2))
    {
        PyErr_SetString(PyExc_TypeError, "output must be a file opened for writing");
    }

    output = (PyFileObject *)arg2;

    if (NULL == (fp = PyFile_AsFile(arg2)))
    {
        ENSURE_EXCEPTION_SET(PyFile_AsFile);
        return NULL;
    }

    Py_INCREF(arg1);
    PyFile_IncUseCount(output);
    Py_BEGIN_ALLOW_THREADS
    xmlSecKeyInfoCtxDebugXmlDump(keyInfoCtx, fp);
    Py_END_ALLOW_THREADS
    PyFile_DecUseCount(output);
    Py_DECREF(arg1);

    Py_RETURN_NONE;
}



static PyObject * xmlsec1_xmlSecKeyDataNameGetKlass(PyObject * self, PyObject * arg)
{
    xmlSecKeyDataId id;
    PyObject * ret;

    if (NULL == (id = xmlSecKeyDataNameGetKlass()))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyDataNameGetKlass);
        return NULL;
    }

    if (NULL == (ret = xmlsec1mod_wrap_xmlSecKeyDataId(id)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_wrap_xmlSecKeyDataId);
        return NULL;
    }

    return ret;
}


static PyObject * xmlsec1_xmlSecKeyDataValueGetKlass(PyObject * self, PyObject * arg)
{
    xmlSecKeyDataId id;
    PyObject * ret;

    if (NULL == (id = xmlSecKeyDataValueGetKlass()))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyDataValueGetKlass);
        return NULL;
    }

    if (NULL == (ret = xmlsec1mod_wrap_xmlSecKeyDataId(id)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_wrap_xmlSecKeyDataId);
        return NULL;
    }

    return ret;
}



static PyObject * xmlsec1_xmlSecKeyDataRetrievalMethodGetKlass(PyObject * self, PyObject * arg)
{
    xmlSecKeyDataId id;
    PyObject * ret;

    if (NULL == (id = xmlSecKeyDataRetrievalMethodGetKlass()))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyDataRetrievalMethodGetKlass);
        return NULL;
    }

    if (NULL == (ret = xmlsec1mod_wrap_xmlSecKeyDataId(id)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_wrap_xmlSecKeyDataId);
        return NULL;
    }

    return ret;
}



static PyObject * xmlsec1_xmlSecKeyDataEncryptedKeyGetKlass(PyObject * self, PyObject * arg)
{
    xmlSecKeyDataId id;
    PyObject * ret;

    if (NULL == (id = xmlSecKeyDataEncryptedKeyGetKlass()))
    {
        ENSURE_EXCEPTION_SET(xmlSecKeyDataEncryptedKeyGetKlass);
        return NULL;
    }

    if (NULL == (ret = xmlsec1mod_wrap_xmlSecKeyDataId(id)))
    {
        ENSURE_EXCEPTION_SET(xmlsec1mod_wrap_xmlSecKeyDataId);
        return NULL;
    }

    return ret;
}


#if 0
-- int xmlSecKeyInfoNodeRead(xmlNodePtr keyInfoNode, xmlSecKeyPtr key, xmlSecKeyInfoCtxPtr keyInfoCtx);
-- int xmlSecKeyInfoNodeWrite(xmlNodePtr keyInfoNode, xmlSecKeyPtr key, xmlSecKeyInfoCtxPtr keyInfoCtx);
-- enum xmlSecKeyInfoMode;
-- #define XMLSEC_KEYINFO_FLAGS_DONT_STOP_ON_KEY_FOUND
-- #define XMLSEC_KEYINFO_FLAGS_STOP_ON_UNKNOWN_CHILD
-- #define XMLSEC_KEYINFO_FLAGS_KEYNAME_STOP_ON_UNKNOWN
-- #define XMLSEC_KEYINFO_FLAGS_KEYVALUE_STOP_ON_UNKNOWN_CHILD
-- #define XMLSEC_KEYINFO_FLAGS_RETRMETHOD_STOP_ON_UNKNOWN_HREF
-- #define XMLSEC_KEYINFO_FLAGS_RETRMETHOD_STOP_ON_MISMATCH_HREF
-- #define XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CHILD
-- #define XMLSEC_KEYINFO_FLAGS_X509DATA_DONT_VERIFY_CERTS
-- #define XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_UNKNOWN_CERT
-- #define XMLSEC_KEYINFO_FLAGS_X509DATA_STOP_ON_INVALID_CERT
-- #define XMLSEC_KEYINFO_FLAGS_ENCKEY_DONT_STOP_ON_FAILED_DECRYPTION
-- #define XMLSEC_KEYINFO_FLAGS_STOP_ON_EMPTY_NODE
-- #define XMLSEC_KEYINFO_FLAGS_X509DATA_SKIP_STRICT_CHECKS
-- struct xmlSecKeyInfoCtx;
-- xmlSecKeyInfoCtxPtr xmlSecKeyInfoCtxCreate(xmlSecKeysMngrPtr keysMngr);
-- void xmlSecKeyInfoCtxDestroy(xmlSecKeyInfoCtxPtr keyInfoCtx);
-- int xmlSecKeyInfoCtxInitialize(xmlSecKeyInfoCtxPtr keyInfoCtx, xmlSecKeysMngrPtr keysMngr);
-- void xmlSecKeyInfoCtxFinalize(xmlSecKeyInfoCtxPtr keyInfoCtx);
-- void xmlSecKeyInfoCtxReset(xmlSecKeyInfoCtxPtr keyInfoCtx);
-- int xmlSecKeyInfoCtxCopyUserPref(xmlSecKeyInfoCtxPtr dst, xmlSecKeyInfoCtxPtr src);
-- int xmlSecKeyInfoCtxCreateEncCtx(xmlSecKeyInfoCtxPtr keyInfoCtx);
-- void xmlSecKeyInfoCtxDebugDump(xmlSecKeyInfoCtxPtr keyInfoCtx, FILE *output);
-- void xmlSecKeyInfoCtxDebugXmlDump(xmlSecKeyInfoCtxPtr keyInfoCtx, FILE *output);
-- #define xmlSecKeyDataNameId
-- xmlSecKeyDataId xmlSecKeyDataNameGetKlass(void);
-- #define xmlSecKeyDataValueId
-- xmlSecKeyDataId xmlSecKeyDataValueGetKlass(void);
-- #define xmlSecKeyDataRetrievalMethodId
-- xmlSecKeyDataId xmlSecKeyDataRetrievalMethodGetKlass(void);
-- #define xmlSecKeyDataEncryptedKeyId
-- xmlSecKeyDataId xmlSecKeyDataEncryptedKeyGetKlass(void);
#endif

#endif
